Add proxy configurations
authorAlex Crichton <alex@alexcrichton.com>
Tue, 9 Sep 2014 02:38:32 +0000 (19:38 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 16 Sep 2014 19:05:21 +0000 (12:05 -0700)
src/cargo/ops/cargo_upload.rs
src/cargo/ops/mod.rs
src/cargo/sources/registry.rs
src/doc/config.md

index 5b30f6759d1d11f91776810c727035c3eb03f7ad..36f6b6a59582bab1f06d1b764425e85840076c1d 100644 (file)
@@ -5,6 +5,7 @@ use std::str;
 use serialize::json;
 
 use curl::http;
+use git2;
 
 use core::source::Source;
 use core::{Package, MultiShell, SourceId};
@@ -55,7 +56,7 @@ fn transmit(pkg: &Package, mut tarball: File,
     let registry_src = SourceId::for_registry(&url);
 
     let url = format!("{}/packages/new", host.trim_right_chars('/'));
-    let mut handle = http::handle();
+    let mut handle = try!(http_handle());
     let mut req = handle.post(url.as_slice(), &mut tarball)
                         .content_length(stat.size as uint)
                         .content_type("application/x-tar")
@@ -129,6 +130,48 @@ pub fn upload_configuration() -> CargoResult<UploadConfig> {
     Ok(UploadConfig { host: host, token: token })
 }
 
+/// Create a new HTTP handle with appropriate global configuration for cargo.
+pub fn http_handle() -> CargoResult<http::Handle> {
+    Ok(match try!(http_proxy()) {
+        Some(proxy) => http::handle().proxy(proxy),
+        None => http::handle(),
+    })
+}
+
+/// Find a globally configured HTTP proxy if one is available.
+///
+/// Favor cargo's `http.proxy`, then git's `http.proxy`, then finally a
+/// HTTP_PROXY env var.
+pub fn http_proxy() -> CargoResult<Option<String>> {
+    let configs = try!(config::all_configs(os::getcwd()));
+    match configs.find_equiv(&"http") {
+        Some(http) => {
+            let http = try!(http.table().chain_error(|| {
+                internal("invalid configuration for the key `http`")
+            }));
+            match http.find_equiv(&"proxy") {
+                Some(proxy) => {
+                    return Ok(Some(try!(proxy.string().chain_error(|| {
+                        internal("invalid configuration for key `http.proxy`")
+                    })).ref0().to_string()))
+                }
+                None => {},
+            }
+        }
+        None => {}
+    }
+    match git2::Config::open_default() {
+        Ok(cfg) => {
+            match cfg.get_str("http.proxy") {
+                Ok(s) => return Ok(Some(s.to_string())),
+                Err(..) => {}
+            }
+        }
+        Err(..) => {}
+    }
+    Ok(os::getenv("HTTP_PROXY"))
+}
+
 pub fn upload_login(shell: &mut MultiShell, token: String) -> CargoResult<()> {
     let config = try!(Config::new(shell, None, None));
     let UploadConfig { host, token: _ } = try!(upload_configuration());
index 5f2da921c79be52f04d5e99625883b6646466d23..ba772460fa4661a7638413888b3547854a7d195f 100644 (file)
@@ -10,7 +10,7 @@ pub use self::cargo_generate_lockfile::{update_lockfile, load_lockfile};
 pub use self::cargo_test::{run_tests, run_benches, TestOptions};
 pub use self::cargo_package::package;
 pub use self::cargo_upload::{upload, upload_configuration, UploadConfig};
-pub use self::cargo_upload::upload_login;
+pub use self::cargo_upload::{upload_login, http_proxy, http_handle};
 
 mod cargo_clean;
 mod cargo_compile;
index 9579484ff34d09a399d1f4af8aa514b2f85b1446..f3e34fe1a1c1a50a7f7374ae5e3f3a153d46aa2d 100644 (file)
@@ -26,7 +26,7 @@ pub struct RegistrySource<'a, 'b:'a> {
     cache_path: Path,
     src_path: Path,
     config: &'a mut Config<'b>,
-    handle: http::Handle,
+    handle: Option<http::Handle>,
     sources: Vec<PathSource>,
     hashes: HashMap<(String, String), String>, // (name, vers) => cksum
 }
@@ -56,7 +56,7 @@ impl<'a, 'b> RegistrySource<'a, 'b> {
             src_path: config.registry_source_path().join(part.as_slice()),
             config: config,
             source_id: source_id.clone(),
-            handle: http::Handle::new(),
+            handle: None,
             sources: Vec::new(),
             hashes: HashMap::new(),
         }
@@ -123,8 +123,15 @@ impl<'a, 'b> RegistrySource<'a, 'b> {
         try!(self.config.shell().status("Downloading", pkg));
 
         try!(fs::mkdir_recursive(&dst.dir_path(), io::UserDir));
+        let handle = match self.handle {
+            Some(ref mut handle) => handle,
+            None => {
+                self.handle = Some(try!(ops::http_handle()));
+                self.handle.as_mut().unwrap()
+            }
+        };
         // TODO: don't download into memory
-        let resp = try!(self.handle.get(url.to_string()).exec());
+        let resp = try!(handle.get(url.to_string()).exec());
         if resp.get_code() != 200 {
             return Err(internal(format!("Failed to get 200 reponse from {}\n{}",
                                         url, resp)))
index 721ace2b273f029b925d30f451a0a9ce65b0747b..b4c38600e3d17ccb2ef1bb9b8eb9eacfb1864002 100644 (file)
@@ -64,4 +64,13 @@ linker = ".."
 # the `$triple` is being compiled for.
 ar = ".."
 linker = ".."
+
+
+# Configuration keys related to the registry
+[registry]
+host = "..."    # URL of the registry (defaults to the central repository)
+token = "..."   # Access token (found on the central repo's website)
+
+[http]
+proxy = "..."   # HTTP proxy to use for HTTP requests (defaults to none)
 ```